package basics.reflect;

import java.lang.reflect.*;

/**
 * 1. 获取class对象的三种方式
 * * 1. Class.forName("全类名")
 * * 2. 类名.class
 * * 3. 对象名.getClass
 * 2. 获取构造方法
 * Constructor constructor = clazz1.getConstructor();  // 无参
 * Constructor constructor = clazz1.getConstructor(String.class); //有参
 * Constructor constructor = clazz1.getDeclaredConstructor(String.class, Integer.class); //获取所有参数的构造器
 * 3. 获取成员变量
 * Field[] fields = clazz1.getFields();
 * Field[] fields = clazz1.getDeclaredFields();
 * 4. 获取成员方法
 * Method[] methods = clazz1.getMethods();
 * Method[] methods = clazz1.getDeclaredMethods()
 *
 * @author chenzhihua
 * @Date 2024/7/16
 */
public class MyRelectDemo {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        /**
         * 获取class对象的三种方式
         *  1. Class.forName("全类名")
         *  2. 类名.class
         *  3. 对象名.getClass
         */
        // 比较常用
        Class clazz1 = Class.forName("basics.reflect.Stu");

        // 一般更多的是当作参数来使用
        Class clazz2 = Stu.class;

        // 当有了这个类的对象是才可以使用
        Stu stu = new Stu();
        Class clazz3 = stu.getClass();

        /**
         * 获取构造方法
         */
        // 获取public的构造方法
//        Constructor[] cons = clazz1.getConstructors();
        // 获取所有构造方法
        Constructor[] cons = clazz1.getDeclaredConstructors();
        for (Constructor con : cons) {
            System.out.println(con);
        }
        System.out.println("========获取单个构造方法==========");
        // 获取单个构造方法
//        Constructor constructor = clazz1.getConstructor();  // 无参
//        Constructor constructor = clazz1.getConstructor(String.class); //有参
        Constructor constructor = clazz1.getDeclaredConstructor(String.class, Integer.class); //获取所有参数的构造器
        System.out.println(constructor);
        System.out.println("===获取名称=====");
        System.out.println(clazz1.getName());
        System.out.println("====获取形参====");
        Parameter[] parameters = constructor.getParameters();
        for (Parameter parameter : parameters) {
            System.out.println(parameter);
        }
        System.out.println("=====创建对象=======");
        constructor.setAccessible(true); // 暴力反射,开启后可以调用私有化的方法
        Stu o = (Stu) constructor.newInstance("张三", 11);
        System.out.println(o);


        System.out.println("=====获取所有的成员变量=======");
        /**
         * 获取所有的成员变量
         */
        Field[] fields = clazz1.getFields();
        for (Field field : fields) {
            System.out.println(field);
        }


        System.out.println("=====获取所有的成员方法=======");
        /**
         * 获取所有的成员方法
         *
         */
        Method[] methods = clazz1.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }


    }
}

class Stu {
    private String name;
    private Integer age;
    public String general;

    public void test() {
        System.out.println("hello");
    }

    public Stu() {

    }

    public Stu(String name) {
        this.name = name;
    }

    private Stu(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "name: " + name + " age: " + age;
    }
}
